//////////////////////////////////////////////////////////////////////////////////////////////////////////
//		            BulletFreezeHinge
//////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma warning (disable: 4819)
#include "CKAll.h"
#include "BulletManager.h"

CKObjectDeclaration	*FillBehaviorBulletFreezeHingeDecl();
CKERROR CreateBulletFreezeHingeProto(CKBehaviorPrototype **);
int BulletFreezeHinge(const CKBehaviorContext& BehContext);

CKObjectDeclaration	*FillBehaviorBulletFreezeHingeDecl()
{
	CKObjectDeclaration *od = CreateCKObjectDeclaration("BulletFreezeHinge");	
	
	od->SetType(CKDLL_BEHAVIORPROTOTYPE);
	od->SetVersion(0x00000001);
	od->SetCreationFunction(CreateBulletFreezeHingeProto);
	od->SetDescription("Bullet Modify Hinge ");
	od->SetCategory("Bullet/Constraint");
	od->SetGuid(CKGUID(0x2630bb0,0x1c1a0193));
	od->SetAuthorGuid(CKGUID(0x457d2f46,0x3ee809a8));
	od->SetAuthorName("gjfeilipu");
	od->SetCompatibleClassId(CKCID_BEOBJECT);

	return od;
}

CKERROR CreateBulletFreezeHingeProto(CKBehaviorPrototype** pproto)
{
	CKBehaviorPrototype *proto = CreateCKBehaviorPrototype("BulletFreezeHinge");
	if (!proto) {
		return CKERR_OUTOFMEMORY;
	}

	proto->DeclareInput("In");
	proto->DeclareOutput("Out");

	proto->DeclareInParameter("Constraint ID",CKPGUID_INT,"-1");
	//proto->DeclareInParameter("LowerLimit",CKPGUID_FLOAT,"0");
	//proto->DeclareInParameter("UpperLimit",CKPGUID_FLOAT,"0");
	//proto->DeclareInParameter("Velocity",CKPGUID_FLOAT,"0.1");
	//proto->DeclareInParameter("MaxMotorImpulse",CKPGUID_FLOAT,"10");
	//proto->DeclareInParameter("KeepAngle",CKPGUID_BOOL);
	proto->DeclareInParameter("Softness",CKPGUID_FLOAT,"0.9");
	proto->DeclareInParameter("BiasFactor",CKPGUID_FLOAT,"0.3");

	//proto->DeclareOutParameter("Constraint ID",CKPGUID_INT,"-1");
	proto->DeclareOutParameter("Angle",CKPGUID_FLOAT,"0");

//----	Local Parameters Declaration

//----	Settings Declaration
//[!output BB_FLAGS]
//[!output BB_CALLBACKREG]
	proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL);
	proto->SetFunction(BulletFreezeHinge);

	*pproto = proto;
	return CK_OK;
}

int BulletFreezeHinge(const CKBehaviorContext& BehContext)
{
	CKBehavior* beh = BehContext.Behavior;
	CKContext* cex = beh->GetCKContext();
	beh->ActivateInput(0, FALSE);
	beh->ActivateOutput(0, TRUE);

	btHingeConstraint* hingeConstraint = NULL;
	BulletManager* bManager =  (BulletManager*)cex->GetManagerByGuid(BulletManagerGUID);
	if(bManager)
	{
		int ID = -1;
		float softness, biasFactor;
		beh->GetInputParameterValue(0, &ID);
		beh->GetInputParameterValue(1, &softness);
		beh->GetInputParameterValue(2, &biasFactor);
		if(-1 != ID)
		{
			hingeConstraint = (btHingeConstraint*)bManager->getConstraint(ID);
			if(hingeConstraint)
			{
				btScalar hingeAngle = hingeConstraint->getHingeAngle();
				beh->SetOutputParameterValue(0, &hingeAngle);
				hingeConstraint->setLimit(hingeAngle, hingeAngle, softness, biasFactor);
				hingeConstraint->enableAngularMotor(false, 0, 0);
			}
		}
	}
	return CKBR_OK;
}